package newDfa;





import DFA.jiexiUtils;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Synthesis {
    private int isMarkedA[];
    private int[] isMarkedB;
    private List<Integer> listdfa1;//不重复DFA1的事件集合(单边+公共)
    private List<Integer> listdfa2;
    private int[][] dfa1;
    private int[][] dfa2;
    private ArrayList show;
    private ArrayList<Integer> mid;//公共事件子集
    private List<Integer> singleA;//DFA1子集
    private List<Integer> singleB;//DFA2子集
    private int dfa1NumberofSingle;
    private int dfa2NumberofSingle;
    private xBuf start = null;
    private int midNumberofCommon;
    private LinkedList X;
    private LinkedList<xBuf> Xnew;//存放状态
    private Integer[] A1;//DFA1横
    private Integer[] A2;
    private TxtReadIn readIn;
    public Integer[] getA1(int[][] dfa, int k) {
        Integer[] temp = new Integer[dfa.length];
        for (int i = 0; i < dfa.length; i++) {
            temp[i] = dfa[i][k];
        }
        return temp;
    }

    public Synthesis() {
    }


    public Synthesis(int[][] dfa1, int[][] dfa2) {
        this.readIn =new TxtReadIn();
        this.listdfa1 = getWayList(dfa1);
        this.listdfa2 = getWayList(dfa2);
        this.Xnew = new LinkedList<>();
        this.X = new LinkedList();
        this.dfa1 = dfa1;
        this.dfa2 = dfa2;
        this.show = new ArrayList();
//        this.midNumberofCommon = getMidNumberofCommon();
//        this.dfa1NumberofSingle = getDfa1NumberofSingle();
//        this.dfa2NumberofSingle = getDfa2NumberofSingle();
//        this.A1 = getA1(dfa1, 1);
//        this.A2 = getA1(dfa2, 1);
        getSingleA();
        getSingleB();
        intialize();
    }

    public void getSingleA() {
        for (int i = 0; i < mid.size(); i++) {
            listdfa1.remove(mid.get(i));
        }
    }

    public void getSingleB() {
        for (int i = 0; i < mid.size(); i++) {
            listdfa2.remove(mid.get(i));
        }
    }

    private int getDfa1NumberofSingle() {
        return listdfa1.size() - midNumberofCommon;
    }

    private int getDfa2NumberofSingle() {
        return listdfa2.size() - midNumberofCommon;
    }

    //listdfa1：dfa1的所用有的事件集合（非重复
    public List getWayList(int[][] dfa) {
        List<Integer> listdfa = new ArrayList<>();
        for (int i = 0; i < dfa.length; i++) {
            if (!listdfa.contains(dfa[i][1]))
                listdfa.add(dfa[i][1]);
        }
//        Integer[] array = listdfa.toArray(new Integer[listdfa.size()]);
//        Arrays.sort(array);
        return listdfa;
    }

    //通过listdfa1集合判断dfa1 和dfa2 的公共事件个数
    private int getMidNumberofCommon() {
        int count = 0;
        mid = new ArrayList<>();
        Integer[] dfa2 = listdfa2.toArray(new Integer[listdfa2.size()]);
        for (int i = 0; i < dfa2.length; i++) {
            if (listdfa1.contains(dfa2[i])) {
                count++;
                mid.add(dfa2[i]);
            }
        }
        //相等
        return count;
    }

    public void intialize() {
        xBuf x0 = new xBuf(dfa1[0][0], dfa2[0][0]);
        //添加展示集合
        ArrayList<showState> show = new ArrayList();
        //添加展示头
        xBuf start;

        Xnew.add(x0);
        X.add(x0);
        DiKaerJi();
    }

    public void DiKaerJi() {
        xBuf buf = null;
        int x1 = 0;
        int x2 = 0;
        while (Xnew != null && Xnew.size() > 0) {
            for (int i = 0; i < X.size(); i++) {
                start = (xBuf) X.get(i);
                buf = (xBuf) X.get(i);
                //得到当前状态的集合的小集合状态
                x1 = buf.getX1();
                x2 = buf.getX2();
                //遍历DFA1的单边事件
                for (int j = 0; j < listdfa1.size(); j++) {
                    singleDFA1(x1, x2, listdfa1.get(j),start);
                }
                //遍历DFA2的单边事件
                for (int j = 0; j < listdfa2.size(); j++) {
                    singleDFA2(x1, x2, listdfa2.get(j),start);
                }
                for (int j = 0; j < mid.size(); j++) {
                    bothActicve(x1, x2, mid.get(j),start);
                }
                Xnew.remove(0);
                //每回减去一个Xnew
                if (Xnew.size() == 0) {
                    //check检查是否还有未综合的DFA
                    jiexiUtils jiexiUtils = new jiexiUtils();
                   // return jiexiUtils.arrErweiGet(show, 3,readIn,stateInHashmapNum);
                }
            }
        }
    }

    private void bothActicve(int x1, int x2, Integer way,xBuf start) {

        for (int j = 0; j < dfa1.length; j++) {
            if (dfa1[j][0] != x1)//找对应的状态
                continue;
            if (dfa1[j][1] != way)//找对应的字符
                continue;
            for (int k = 0; k < dfa2.length; k++) {
                if (dfa2[k][0] != x2)//找对应的状态
                    continue;
                if (dfa2[k][1] != way)//找对应的字符
                    continue;
                xBuf Xmember = new xBuf(dfa1[j][2], dfa2[k][2]);
                showState state = new showState(start, way, Xmember);
                show.add(state);
                if (Xmember.isPossessState(dfa1[j][2], dfa2[k][2], Xmember, X)) {
                    Xnew.add(Xmember);
                }
                break;
            }
            break;
        }
    }
        public void singleDFA2 ( int x1, int x2, Integer way,xBuf start){
            for (int i = 0; i < dfa2.length; i++) {
                if (dfa2[i][0] != x2) continue;//排除状态不等于x2的
                if (dfa2[i][1] != way) continue;
                xBuf Xmember = new xBuf(x1, dfa2[i][2]);
                showState state = new showState(start, way, Xmember);
                show.add(state);
                if (Xmember.isPossessState(x1, dfa2[i][2], Xmember, X)) {
                    Xnew.add(Xmember);
                }
                break;
            }
        }
        public void singleDFA1 ( int x1, int x2, int way,xBuf start){
            for (int i = 0; i < dfa1.length; i++) {
                if (dfa1[i][0] != x1) continue;//排除状态不等于x1的
                if (dfa1[i][1] != way) continue;
                xBuf Xmember = new xBuf(dfa1[i][2], x2);
                showState state = new showState(start, way, Xmember);
                show.add(state);
                if (Xmember.isPossessState(dfa1[i][2], x2, Xmember, X)) {
                    Xnew.add(Xmember);
                }
                break;
            }
        }
    }

